//启用express服务，处理api网络请求
const express = require('express');

//JsonWebToken，用来验证身份，保证安全性
const jwts = require('jsonwebtoken');

//加密
const bcrypt = require('bcrypt');

//数据库连接
const db = require('./db');

//配置文件
const config = require('./config.json');

//华为云SDK和TOKEN文件
const core = require('@huaweicloud/huaweicloud-sdk-core');
const iotda = require("@huaweicloud/huaweicloud-sdk-iotda/v5/public-api");
const token = require('./token.json');

//express路径创建
const router = express.Router();

//华为云的AK和SK密钥
const ak = token.ak;
const sk = token.sk;

//MQTT服务器地址与产品ID
const endpoint = "https://iotda.cn-north-4.myhuaweicloud.com";
const project_id = "7ca5090c9ecb43f4a3ee138400ed98df";

//datas缓存
let datas = "";

//华为云连接
const credentials = new core.BasicCredentials()
	.withAk(ak)
	.withSk(sk)
	.withProjectId(project_id)
const client = iotda.IoTDAClient.newBuilder()
	.withCredential(credentials)
	.withEndpoint(endpoint)
	.build();


//获取数据函数
function fetchData() {
	const request = new iotda.ShowDeviceShadowRequest();
	request.deviceId = "660974affb8177243a534265_hi3861";
	const result = client.showDeviceShadow(request);
	result.then(result => {
		//将数据保存在缓存中
		datas = result.shadow[0].reported.properties;
		//数据保存在数据库中
		db.saveDataToDatabase(result.shadow[0].reported);
	}).catch(ex => {
		console.log("exception:" + JSON.stringify(ex));
	});
}

//每4.8秒更新一次缓存
setInterval(fetchData, 4800);

//用户注册，使用API锁，远端设备需要请求后再注册
router.post('/register', async (req, res) => {
	const {
		username,
		password
	} = req.body;

	console.log(username, password);

	if (!username || !password) {
		return res.status(400).json({
			message: '用户名和密码不能为空'
		});
	}

	// 检查用户名是否已存在
	const user = await db.getUser(username);
	if (user) {
		return res.status(400).json({
			message: '用户名已存在'
		});
	}

	// 创建用户
	const salt = await bcrypt.genSalt(6);
	const hash = await bcrypt.hash(password, salt);
	await db.createUser(username, hash, null, null);

	console.log('\x1b[32m%s\x1b[0m users “' + username + '” Registed', '[INFO]:');

	res.json({
		message: '注册成功'
	});
});

// 用户登录
router.post('/login', async (req, res) => {
	const {
		username,
		password
	} = req.body;
	if (!username || !password) {
		return res.status(400).json({
			message: '用户名和密码不能为空'
		});
	}

	// 检查用户名和密码是否匹配
	const user = await db.getUser(username);
	if (!user || !await bcrypt.compare(password, user.password)) {

		console.log('\x1b[33m%s\x1b[0m users “' + username + '” Logining but error', '[WARN]:');

		return res.status(400).json({
			message: '用户名或密码错误'
		});
	}

	function sleep(ms) {
		return new Promise(resolve => setTimeout(resolve, ms));
	}

	await sleep(1000); // 休眠 1 秒

	// 生成jwt
	const payload = {
		username: user.username,
		id: user.id,
		role: user.role
	};
	const token = jwts.sign(payload, config.jwtSecret, {
		expiresIn: '6h'
	});

	console.log('\x1b[32m%s\x1b[0m users “' + username + '” Logined' + ' With role: ' + user.role,
		'[INFO]:');

	console.log(datas);

	res.json({
		token
	});
});

//获取数据
router.post('/get_data', async (req, res) => {
	const {
		jwt
	} = req.body;

	//正则表达从JSON数据中提取出TOKEN
	const token = jwt.replace(/^"(.*)"$/, '$1');

	jwts.verify(token, config.jwtSecret, (err, decoded) => {
		if (err) {
			return res.status(500).json({
				message: 'jwt验证失败，请重新登陆'
			});
		}
	});
	res.json(datas);
});

//获取即时数据
router.post('/get_data_imd', async (req, res) => {
	const {
		jwt
	} = req.body;

	//正则表达从JSON数据中提取出TOKEN
	const token = jwt.replace(/^"(.*)"$/, '$1');

	await this.fetchData;

	jwts.verify(token, config.jwtSecret, (err, decoded) => {
		if (err) {
			return res.status(500).json({
				message: 'jwt验证失败，请重新登陆'
			});
		}
	});
	res.json(datas);
});

router.post('/led', async (req, res) => {
	const {
		sta
	} = req.body;
	const request = new iotda.CreateCommandRequest();
	request.deviceId = "660974affb8177243a534265_hi3861";
	request.instanceId = "f2cf8829-804b-4039-9736-bc8ac7e3f5a0";

	if (sta == 0) {
		const body = new iotda.DeviceCommandRequest();
		body.withParas("{\"value\":\"OFF\"}");
		body.withCommandName("led");
		body.withServiceId("attribute");
		request.withBody(body);
		const result = client.createCommand(request);
		result.then(result => {
			res.json({
				message: 'COMMAND_SET_LED_D'
			});
		}).catch(ex => {
			console.log("exception:" + JSON.stringify(ex));
		});
	} else {
		const body = new iotda.DeviceCommandRequest();
		body.withParas("{\"value\":\"ON\"}");
		body.withCommandName("led");
		body.withServiceId("attribute");
		request.withBody(body);
		const result = client.createCommand(request);
		result.then(result => {
			res.json({
				message: 'COMMAND_SET_LED_L'
			});
		}).catch(ex => {
			console.log("exception:" + JSON.stringify(ex));
		});
	}
});

router.post('/sig', async (req, res) => {
	const {
		sta
	} = req.body;
	const request = new iotda.CreateCommandRequest();
	request.deviceId = "660974affb8177243a534265_hi3861";
	request.instanceId = "f2cf8829-804b-4039-9736-bc8ac7e3f5a0";

	if (sta == 0) {
		const body = new iotda.DeviceCommandRequest();
		body.withParas("{\"value\":\"OFF\"}");
		body.withCommandName("sig");
		body.withServiceId("attribute");
		request.withBody(body);
		const result = client.createCommand(request);
		result.then(result => {}).catch(ex => {
			console.log("exception:" + JSON.stringify(ex));
		});
	} else {
		const body = new iotda.DeviceCommandRequest();
		body.withParas("{\"value\":\"ON\"}");
		body.withCommandName("sig");
		body.withServiceId("attribute");
		request.withBody(body);
		const result = client.createCommand(request);
		result.then(result => {}).catch(ex => {
			console.log("exception:" + JSON.stringify(ex));
		});
	}
});

module.exports = router;